
//
// 20120825 - AH - Created.
// 20120906 - AH - Missing java doc.
// 20120908 - AH - show(TestForestFactory, boolean).
// 20121001 - AH - Stopped performing tests in a depth first search sequence
//                 but performs all paths from roots to all leafs independently.
// 20121111 - AH - Created from former TestTreeManager which now contains panels
//                 of this type to run sequences of test over one type of world.
//

package org.japril.jhut.swing;

import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.io.CharArrayWriter;
import java.io.PrintWriter;
import java.util.List;

import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.JTextArea;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;

import org.japril.jhut.framework.JhutTest;
import org.japril.jhut.framework.TestContext;
import org.japril.jhut.framework.TestFactory;
import org.japril.jhut.framework.TreeTestPaths;

/**
 * <p>
 *   Swing applications for running 
 *   {@link JhutTest} tests.
 * </p>
 * @author Arne Halvorsen (AH)
 */
@SuppressWarnings("serial")
public final class TestTreeManagerPanel extends JPanel
{
  private final List<JhutTest> m_forest;
  
  private final TestFactory m_factory;
  
  private final String m_wname;
  
  private final TestTreeView m_treeView=new TestTreeView();
  
  private final JTextArea m_worldTextArea=new JTextArea();
  
  private final JTextArea m_logTextArea=new JTextArea();
  
  private final CharArrayWriter m_cawLog=new CharArrayWriter();
  
  private final PrintWriter m_pwLog=new PrintWriter(m_cawLog);
  
  private final CharArrayWriter m_cawWorld=new CharArrayWriter();
  
  private final PrintWriter m_pwWorld=new PrintWriter(m_cawWorld);
  
  private final TestContext m_context=new TestContext()
  {  
    public void log(String txt)
    {
      m_pwLog.println(txt);
      m_pwLog.flush();
      String t=m_cawLog.toString();
      m_logTextArea.setText(t);
    }

    public void testStarts(JhutTest[] path)
    { 
      String p2s=JhutTest.pathToString(path);
      
      System.out.println("testStarts: "+p2s);
      
      m_pwLog.println();
      m_pwLog.println(p2s);
      m_pwLog.println();
      String t=m_cawLog.toString();
      m_logTextArea.setText(t);
      
      m_pwWorld.println();
      m_pwWorld.println(p2s);
      m_pwWorld.println();
      t=m_cawWorld.toString();
      m_worldTextArea.setText(t);
    }


    public void testStart(JhutTest test)
    {
      m_pwLog.println();
      m_pwLog.println("-----");
      m_pwLog.println();
      m_pwLog.println("Test: '"+test.getName()+"' starts");
      m_pwLog.flush();
      String t=m_cawLog.toString();
      m_logTextArea.setText(t);
    }

    public void testEnd(JhutTest test)
    {
      String name=test.getName();
      
      m_pwLog.println();
      m_pwLog.println("Test: "+name+" ended");
      m_pwLog.flush();
      String t=m_cawLog.toString();
      m_logTextArea.setText(t);
      
      m_pwWorld.println("World after test: ");
      m_pwWorld.println();
      m_pwWorld.flush();
      t=m_cawWorld.toString();
      m_worldTextArea.setText(t);
    }
    
  };
  
  /**
   * <p>
   *   Constructor.
   * </p>
   * @param forest Forest that defines the test sequences (all paths to all
   *               leafs).
   * @param f      {@link TestFactory} to create tests.
   * @param wname  Name on world to run paths over, may be {@code null}.
   */
  public TestTreeManagerPanel(List<JhutTest> forest, TestFactory tf, 
    String wname)
  {
    if (forest==null)
    {
      throw new NullPointerException("forest");
    }
    
    m_forest=forest;
    
    m_factory=tf;
    
    m_wname=wname;
    
    setLayout(new BorderLayout());
    
    m_treeView.addTreeSelectionListener
    (
      new TreeSelectionListener()
      {
        public void valueChanged(TreeSelectionEvent e)
        {
          JhutTest test=m_treeView.getSelected();
          
          boolean testSelected=(test!=null);
          
          m_showTestInfoAction.setEnabled(testSelected);
        }
      }
    );
    
    JSplitPane center=new JSplitPane(JSplitPane.VERTICAL_SPLIT);
    
    JSplitPane horSplit=new JSplitPane();
    horSplit.setLeftComponent(m_treeView);
    JPanel textAreaPanel=new JPanel(new BorderLayout());
    textAreaPanel.add(new JLabel("Test Logging"), BorderLayout.NORTH);
    textAreaPanel.add(new JScrollPane(m_logTextArea), BorderLayout.CENTER);
    horSplit.setRightComponent(textAreaPanel);
    
    horSplit.setDividerLocation(200);
    
    center.setLeftComponent(horSplit);
    textAreaPanel=new JPanel(new BorderLayout());
    textAreaPanel.add(new JLabel("World Presentations"), BorderLayout.NORTH);
    textAreaPanel.add(new JScrollPane(m_worldTextArea), BorderLayout.CENTER);
    center.setRightComponent(textAreaPanel);
    
    center.setDividerLocation(200);
    
    add(center, BorderLayout.CENTER);
    
    JPanel buttons=new JPanel(new FlowLayout(FlowLayout.CENTER));
    buttons.add(new JButton(m_performAction));
    buttons.add(new JButton(m_showTestInfoAction));
    add(buttons, BorderLayout.SOUTH);
    
    init();
  }
  
  void init()
  {
    m_cawLog.reset();
    m_logTextArea.setText("");
    
    m_cawWorld.reset();
    m_worldTextArea.setText("");
   
    m_treeView.setContent(m_forest);
    m_performAction.setEnabled(true);
  }
  
  private final Action m_performAction=new AbstractAction("Perform")
  {
    {
      setEnabled(false);
    }
    
    public void actionPerformed(ActionEvent e){ perform(); }
    
  };
  
  private void perform()
  {
    List<JhutTest> tests=m_treeView.getContent();
    TreeTestPaths ttp=new TreeTestPaths(tests);
    
    ttp.performTests(m_context, m_factory, m_wname);
      
    m_treeView.setContent(tests);
    m_performAction.setEnabled(false);
  }
  
  private final TestInfoDialog m_tid=new TestInfoDialog();
  
  private Action m_showTestInfoAction=new AbstractAction("Test Info")
  {
    {
      setEnabled(false);  
    }
    
    public void actionPerformed(ActionEvent e)
    {
      JhutTest node=m_treeView.getSelected();
      if (node!=null)
      {
        m_tid.show(node);  
      }
    }
  };
  
}
